gusucode.com > 各种VC自绘控件源码程序 > 各种VC自绘控件源码/code/SkinControls(自绘MFC基本控件 )/SkinControls/SkinControls/SkinButton.cpp

    
#include "stdafx.h"
#include "Resource.h"
#include "SkinButton.h"

//////////////////////////////////////////////////////////////////////////

IMPLEMENT_DYNAMIC(CSkinButton, CButton)

BEGIN_MESSAGE_MAP(CSkinButton, CButton)
	ON_WM_CREATE()
	ON_WM_MOUSEMOVE()
	ON_WM_ERASEBKGND()
	//ON_WM_SETCURSOR()
	ON_MESSAGE(WM_MOUSELEAVE,OnMouseLeave)
END_MESSAGE_MAP()

//////////////////////////////////////////////////////////////////////////

//提示 ID
#define TOOLTIP_ID					100

//////////////////////////////////////////////////////////////////////////

//构造函数
CSkinButton::CSkinButton()
{
	m_bHovering=false;
	m_bShowTextFrame=false;
	m_crTextColor=RGB(0,0,0);
	m_crTextFrameColor=DEF_TEXT_FRAME_COLOR;
}

//析构函数
CSkinButton::~CSkinButton()
{
}

//对象附加到现有窗口
void CSkinButton::PreSubclassWindow()
{
	__super::PreSubclassWindow();
	SetButtonStyle(GetButtonStyle()|BS_OWNERDRAW);
	//CreateControlRgn();
	return;
}

//消息解释
BOOL CSkinButton::PreTranslateMessage(MSG * pMsg)
{
	if(  m_ToolTip.m_hWnd != NULL  )
		m_ToolTip.RelayEvent(pMsg);
	return CButton::PreTranslateMessage(pMsg);
}

//建立消息
int CSkinButton::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (__super::OnCreate(lpCreateStruct)==-1) return -1;
	SetButtonStyle(GetButtonStyle()|BS_OWNERDRAW);
	//CreateControlRgn();
	return 0;
}

//设置提示
void CSkinButton::SetToolTips(LPCTSTR pszTips)
{
	m_strTips = pszTips;

	UpdateToolTip();
}

//创建区域
bool CSkinButton::CreateControlRgn()
{
	//非透明部分的RGN
	CRgn rgnControl;
	rgnControl.CreateRectRgn(0,0,0,0);
	//创建区域
	DWORD w = m_ImageBack.GetWidth()/4;
	for (DWORD nYPos = 0; nYPos < m_ImageBack.GetHeight(); nYPos++)
	{
		for (DWORD nXPos = 0;nXPos < w; nXPos++)
		{
			DWORD nXStartPos=nXPos;

			//透明判断
			do
			{
				if (m_ImageBack.IsTransparent(nXPos, m_ImageBack.GetHeight() - nYPos - 1)) break;
			} while ((++nXPos) < w);

			if ((nXPos - nXStartPos) > 0)
			{
				//创建区域
				CRgn RgnUnite;
				RgnUnite.CreateRectRgn(nXStartPos,nYPos,nXPos,nYPos+1);

				//合并区域
				CombineRgn(rgnControl,RgnUnite,rgnControl,RGN_OR);
			}
		}
	}
	SetWindowRgn(rgnControl,TRUE);
	SetWindowPos(NULL,0,0,w,m_ImageBack.GetHeight(),SWP_NOMOVE|SWP_NOACTIVATE);


	return true;
}

//更新提示
void CSkinButton::UpdateToolTip()
{
	if (GetSafeHwnd())
	{
		if (m_ToolTip.GetSafeHwnd()==NULL) m_ToolTip.Create(this);
		if (m_strTips.IsEmpty()==false)
		{
			CRect ClientRect;
			GetClientRect(&ClientRect);
			m_ToolTip.Activate(TRUE);
			m_ToolTip.AddTool(this,m_strTips,&ClientRect,TOOLTIP_ID);
		}
		else m_ToolTip.Activate(FALSE);
	}
	return;
}

//设置颜色
bool CSkinButton::SetTextColor(COLORREF crTextColor,COLORREF crTextFrameColor,bool bShowFrame)
{
	m_crTextColor=crTextColor;
	m_bShowTextFrame=bShowFrame;
	m_crTextFrameColor=crTextFrameColor;

	if (GetSafeHwnd()) Invalidate(FALSE);
	return true;
}


//加载位图
bool CSkinButton::SetButtonImage(LPCTSTR pszFileName, DWORD imagetype)
{
	//效验参数
	ASSERT(pszFileName);
	if (pszFileName==NULL) return false;

	//加载图
	m_ImageBack.Load(pszFileName,imagetype);
	m_ImageBack.SetTransIndex(0);
	m_ImageBack.SetTransColor(CxImage::RGBtoRGBQUAD(TRANS_COLOR));

	//调整位置
	if (GetSafeHwnd()) CreateControlRgn();

	return true;
}

//加载位图
bool CSkinButton::SetButtonImage(HRSRC hRes, DWORD imagetype, HMODULE hModule)
{
	m_ImageBack.LoadResource(hRes, imagetype, hModule);
	m_ImageBack.SetTransIndex(0);
	m_ImageBack.SetTransColor(CxImage::RGBtoRGBQUAD(TRANS_COLOR));

	if (GetSafeHwnd()) CreateControlRgn();

	return true;
}

//鼠标移动消息
void CSkinButton::OnMouseMove(UINT nFlags, CPoint point)
{
	if (m_bHovering==false)
	{
		//注册消息
		m_bHovering=true;
		Invalidate(FALSE);
		TRACKMOUSEEVENT TrackMouseEvent;
		TrackMouseEvent.cbSize=sizeof(TrackMouseEvent);
		TrackMouseEvent.dwFlags=TME_LEAVE;
		TrackMouseEvent.hwndTrack=GetSafeHwnd();
		TrackMouseEvent.dwHoverTime=HOVER_DEFAULT;
		_TrackMouseEvent(&TrackMouseEvent);
	}
	__super::OnMouseMove(nFlags, point);
}

//鼠标离开消息
LRESULT CSkinButton::OnMouseLeave(WPARAM wparam, LPARAM lparam)
{
	m_bHovering=false;
	Invalidate(FALSE);
	return 0;
}

//背景函数
BOOL CSkinButton::OnEraseBkgnd(CDC * pDC)
{
	Invalidate(FALSE);
	UpdateWindow();
	return TRUE;
}

//光标消息
BOOL CSkinButton::OnSetCursor(CWnd * pWnd, UINT nHitTest, UINT message)
{
	::SetCursor(GetSysHandCursor());
	return TRUE;
}

//界面绘画函数
void CSkinButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
	//定义变量
	CRect ClientRect;
	GetClientRect(&ClientRect);
	bool bDisable=((lpDrawItemStruct->itemState&ODS_DISABLED)!=0);
	bool bButtonDown=((lpDrawItemStruct->itemState&ODS_SELECTED)!=0);

	//设置 DC
	HDC hDC=lpDrawItemStruct->hDC;

	//获取文字
	CString strText;
	GetWindowText(strText);

	//加载背景图
	if (m_ImageBack.IsValid())
	{
		//计算位图位置
		int iPartWidth=m_ImageBack.GetWidth()/4,iDrawPos=0;
		if (bDisable) iDrawPos=iPartWidth*3;
		else if (bButtonDown) iDrawPos=iPartWidth*2;
		else if (m_bHovering) iDrawPos=iPartWidth;
		else iDrawPos=0;

		//下面这个是焦点时候 有需要的把背景图的状态数加1个 然后把下面的加上 
		//if (lpDrawItemStruct->itemState&ODS_FOCUS) iDrawPos=iPartWidth*3;

		m_ImageBack.Draw(hDC, 0, 0, iPartWidth, m_ImageBack.GetHeight(), iDrawPos, 0, iPartWidth, m_ImageBack.GetHeight());
	}
	else
	{
		//绘画默认界面
		CDC * pDC=CDC::FromHandle(hDC);
		pDC->FillSolidRect(&ClientRect,GetSysColor(COLOR_BTNFACE));
		if (bButtonDown) pDC->Draw3dRect(&ClientRect,GetSysColor(COLOR_WINDOWFRAME),GetSysColor(COLOR_3DHILIGHT));
		else pDC->Draw3dRect(&ClientRect,GetSysColor(COLOR_3DHILIGHT),GetSysColor(COLOR_WINDOWFRAME));
	}

	//绘画字体
	ClientRect.top+=1;
	::SetBkMode(hDC,TRANSPARENT);
	if(!m_bShowTextFrame)
	{
		if (bDisable) ::SetTextColor(hDC,GetSysColor(COLOR_GRAYTEXT));
		else ::SetTextColor(hDC,m_crTextColor);
		DrawText(hDC,strText,strText.GetLength(),ClientRect,DT_CENTER|DT_VCENTER|DT_SINGLELINE|DT_END_ELLIPSIS);
	}
	//艺术字体
	else
	{
		CDC * pDC=CDC::FromHandle(hDC);
		DrawTextString(pDC,strText,m_crTextColor,m_crTextFrameColor,ClientRect);
	}

	return;
}

//艺术字体
void CSkinButton::DrawTextString(CDC * pDC, LPCTSTR pszString, COLORREF crText, COLORREF crFrame, LPRECT lpRect)
{
	//变量定义
	int nStringLength=lstrlen(pszString);
	int nXExcursion[8]={1,1,1,0,-1,-1,-1,0};
	int nYExcursion[8]={-1,0,1,1,1,0,-1,-1};

	//绘画边框
	pDC->SetTextColor(crFrame);
	CRect rcDraw;
	for (int i=0;i<sizeof(nXExcursion);i++)
	{
		rcDraw.CopyRect(lpRect);
		rcDraw.OffsetRect(nXExcursion[i],nYExcursion[i]);
		pDC->DrawText(pszString,nStringLength,&rcDraw,DT_VCENTER|DT_CENTER|DT_SINGLELINE|DT_END_ELLIPSIS);
	}

	//绘画字体
	rcDraw.CopyRect(lpRect);
	pDC->SetTextColor(crText);
	pDC->DrawText(pszString,nStringLength,&rcDraw,DT_VCENTER|DT_CENTER|DT_SINGLELINE|DT_END_ELLIPSIS);

	return;
}

//艺术字体
void CSkinButton::DrawTextString(CDC * pDC, LPCTSTR pszString, COLORREF crText, COLORREF crFrame, int nXPos, int nYPos)
{
	//变量定义
	int nStringLength=lstrlen(pszString);
	int nXExcursion[8]={1,1,1,0,-1,-1,-1,0};
	int nYExcursion[8]={-1,0,1,1,1,0,-1,-1};

	//绘画边框
	pDC->SetTextColor(crFrame);
	for (int i=0;i<sizeof(nXExcursion);i++)
	{
		pDC->TextOut(nXPos+nXExcursion[i],nYPos+nYExcursion[i],pszString,nStringLength);
	}

	//绘画字体
	pDC->SetTextColor(crText);
	pDC->TextOut(nXPos,nYPos,pszString,nStringLength);

	return;
}

//////////////////////////////////////////////////////////////////////////